package com.liry.custommvc;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author ALI
 * @since 2022/10/5
 */
public class DispatcherServlet extends HttpServlet {

    /** 映射处理器 */
    private static Collection<HandlerMapping> handlerMappingList = new ArrayList<>();
    /** 映射处理器适配器 */
    private static Collection<HandlerAdapter> handlerAdapterList = new ArrayList<>();

    public DispatcherServlet(AnnotationConfigApplicationContext applicationContext) {
        handlerMappingList = applicationContext.getBeansOfType(HandlerMapping.class).values();
        handlerAdapterList = applicationContext.getBeansOfType(HandlerAdapter.class).values();
    }

    private HttpRequestHandler getHandlerMapping(HttpServletRequest req) {
        for (HandlerMapping handlerMapping : handlerMappingList) {
            return handlerMapping.getHandler(req);
        }
        return null;
    }

    private HandlerAdapter getHandlerAdapter(HttpServletRequest req, HttpServletResponse resp,
                                             HttpRequestHandler handler) {
        for (HandlerAdapter handlerAdapter : handlerAdapterList) {
            if (handlerAdapter.supports(handler)) {
                return handlerAdapter;
            }
        }
        return null;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpRequestHandler httpRequestHandler = getHandlerMapping(req);
        if (httpRequestHandler == null) {
            System.out.println("找不到映射处理器");
            return;
        }

        HandlerAdapter handlerAdapter = getHandlerAdapter(req, resp, httpRequestHandler);
        if (handlerAdapter == null) {
            System.out.println("找不到映射处理器适配器");
            return;
        }
        Object result = null;
        try {
            result = handlerAdapter.handle(req, resp, httpRequestHandler);
        } catch (Exception e) {
            throw new RuntimeException("映射适配器处理结果异常");
        }

        PrintWriter writer = resp.getWriter();
        writer.println(result);
        writer.flush();
        writer.close();
    }
}
